package com.glodon.paas.document.biz.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import com.glodon.paas.consts.StringConst;
import com.glodon.paas.document.constant.DocumentConstant;
import com.glodon.paas.document.biz.ShareBiz;
import com.glodon.paas.document.dao.FileDao;
import com.glodon.paas.document.dao.PublicTokenDao;
import com.glodon.paas.document.dao.ShareDao;
import com.glodon.paas.document.dao.domain.FileInfoEntity;
import com.glodon.paas.document.dao.domain.PublicTokenEntity;
import com.glodon.paas.document.dao.domain.ShareEntity;
import com.glodon.paas.document.service.util.WebService;
import com.glodon.paas.dto.DataTansitionObject;
import com.glodon.paas.exception.PaasServerExceptionFactory;
import com.glodon.paas.exception.i18n.ErrorCode;
import com.glodon.paas.util.TokenGenerator;
import com.glodon.paas.util.UUIDUtil;

@Repository("shareBiz")
public class ShareBizImpl implements ShareBiz {

    public static final Logger LOGGER = LoggerFactory.getLogger(ShareBizImpl.class);

    @Autowired
    private ShareDao           shareDao;

    @Autowired
    private FileDao            fileDao;

    @Autowired
    private PublicTokenDao     publicTokenDao;
    
    @Autowired
    private WebService webService;

    // @Override
    // public boolean isSharedForUser(String userId, String fileId) {
    // if(StringUtils.isEmpty(userId)){
    // throw PaasServerExceptionFactory.validateException("userId is empty.", null);
    // }
    // if(StringUtils.isEmpty(fileId)){
    // throw PaasServerExceptionFactory.validateException("fileId is empty.", null);
    // }
    //
    // return checkSharedFile(userId, fileId);
    // }

    private boolean checkSharedFile(String userId, String fileId) {
        if (StringUtils.isEmpty(fileId)) {
            return false;
        } else {
            if (this.getShareForMe(userId, fileId) != null) {
                return true;
            } else {
                return checkSharedFile(userId, fileDao.getParentId(fileId));
            }
        }
    }

    @Override
    public List<ShareEntity> getSharesByMe(String userId, String fileId, Integer shareType) {
        if (StringUtils.isEmpty(userId)) {
            throw PaasServerExceptionFactory.validateException("userId is empty.", null);
        } else {
            return shareDao.getShareByMe(userId, fileId, shareType);
        }
    }

    @Override
    public List<ShareEntity> getSharesForMe(String userId, String fileId) {
        if (StringUtils.isEmpty(userId)) {
            throw PaasServerExceptionFactory.validateException("userId is empty.", null);
        } else {
            return shareDao.getShareForMe(userId, fileId);
        }
    }

    @Override
    public void remove(String userId, String fileId) {
        ShareEntity share = this.getShareForMe(userId, fileId);
        if (share != null) {
            shareDao.delete(share.getId());
        } else {
            throw PaasServerExceptionFactory.notFoundException("can not find this share relation.", null);
        }
    }

    @Override
    public void remove(String fileId, Integer shareType) {
        shareDao.deleteByFile(fileId, shareType);
    }

    // @Override
    // public List<ShareEntity> getSharesByMe(String userId, String fileId) {
    // if(StringUtils.isEmpty(userId)){
    // throw PaasServerExceptionFactory.validateException("userId is empty.", null);
    // }
    // if(StringUtils.isEmpty(fileId)){
    // throw PaasServerExceptionFactory.validateException("fileId is empty.", null);
    // }
    // return shareDao.getShareByMe(userId, fileId, DocumentConstant.SHARE_TYPE_SHARED);
    // }

    @Override
    public ShareEntity getShareForMe(String userId, String fileId) {
        if (StringUtils.isEmpty(userId)) {
            throw PaasServerExceptionFactory.validateException("userId is empty.", null);
        }
        if (StringUtils.isEmpty(fileId)) {
            throw PaasServerExceptionFactory.validateException("fileId is empty.", null);
        }
        List<ShareEntity> rs = shareDao.getShareForMe(userId, fileId);
        if (rs == null || rs.size() == 0) {
            return null;
        } else if (rs.size() > 1) {
            LOGGER.warn("select one share info file id:{} for User id:{},1 too many result items.");
        }
        return shareDao.getShareForMe(userId, fileId).get(0);
    }

    // @Override
    // public void save(ShareEntity share) {
    // if(share == null){
    // throw PaasServerExceptionFactory.validateException("Share data is empty.", null);
    // }
    // shareDao.insert(share);
    // }

    @Override
    public List<DataTansitionObject> getNavigation(String userId, String fileId) {
        if (StringUtils.isEmpty(userId)) {
            throw PaasServerExceptionFactory.validateException("userId is empty.", null);
        }
        if (StringUtils.isEmpty(fileId)) {
            throw PaasServerExceptionFactory.validateException("fileId is empty.", null);
        }

        List<DataTansitionObject> ns = new ArrayList<DataTansitionObject>();
        FileInfoEntity file = fileDao.get(fileId);
        while (file != null) {
            DataTansitionObject n = new DataTansitionObject();
            n.setId(file.getId());
            n.setName(file.getName());
            ns.add(0, n);
            ShareEntity share;
            share = this.getShareForMe(userId, file.getId());
            if (share != null) {
                break;
            }
            file = fileDao.get(file.getParentId());
        }
        return ns;
    }

    @Override
    public boolean isSharedFile(String fileId) {
        if (StringUtils.isEmpty(fileId)) {
            throw PaasServerExceptionFactory.validateException("fileId is empty.", null);
        }
        return shareDao.isSharedFile(fileId);
    }

    @Override
    public long getShareCount(String fileId) {
        return shareDao.getShareCount(fileId, DocumentConstant.SHARE_TYPE_SHARED);
    }

    @Override
    public ShareEntity share(String userId, String fileId, String sharerId, String privilege) {
        if (userId.equals(sharerId)) {
            throw PaasServerExceptionFactory.documentException("you can not share file to yourself!", null).setErrorCode(ErrorCode.SHARE_FILE_TO_SELF);
        }
        ShareEntity share = this.getShareForMe(sharerId, fileId);
        if (share == null) {
            share = new ShareEntity();
            share.setId(UUIDUtil.getUUIDStr());
            share.setFileId(fileId);
            share.setSharedUserId(userId);
            share.setCreatedTime(new Date());
            share.setToUserId(sharerId);
            if (sharerId.equals(StringConst.ANONYMOUS_USERID)) {
                share.setShareType(DocumentConstant.SHARE_TYPE_PUBLISHED);
            } else {
                share.setShareType(DocumentConstant.SHARE_TYPE_SHARED);
            }
            if (StringConst.WRITE.equalsIgnoreCase(privilege)) {
                share.setPrivilege(DocumentConstant.SHARE_PRIVILEGE_WRITE);
            } else {
                share.setPrivilege(DocumentConstant.SHARE_PRIVILEGE_READ);
            }
            shareDao.insert(share);
        }
        return share;
    }

    @Override
    public boolean isPublishedFile(String fileId) {
        if (StringUtils.isEmpty(fileId)) {
            throw PaasServerExceptionFactory.validateException("fileId is empty.", null);
        }
        return shareDao.isPublishedFile(fileId);
    }

    @Override
    public String publish(String userId, FileInfoEntity file) {
        if (!this.isPublishedFile(file.getId())) {
            this.share(userId, file.getId(), StringConst.ANONYMOUS_USERID, StringConst.READ);
        }
        PublicTokenEntity pt = publicTokenDao.get(file.getId());
        if (pt == null) {
            pt = new PublicTokenEntity();
            pt.setFileId(file.getId());
            pt.setToken(TokenGenerator.generate(UUIDUtil.getUUIDStr()));
            pt.setOwnerId(userId);
            pt.setUpdateTime(new Date());
            publicTokenDao.insert(pt);
        }
        if (StringUtils.isNotBlank(file.getDataBagId()) && StringUtils.isBlank(pt.getDatabagToken())) {
            String databagToken = webService.publicDataBag(file.getDataBagId());
            if (databagToken != null) {
                pt.setDatabagToken(databagToken);
                publicTokenDao.update(pt);
            }
        }
        return pt.getToken();
    }

    @Override
    public PublicTokenEntity getPublishInfoByToken(String token) {
        return publicTokenDao.getByToken(token);
    }

    @Override
    public PublicTokenEntity getPublishInfoByFile(String fileId) {
        return publicTokenDao.get(fileId);
    }

    @Override
    public void removeToken(String fileId) {
        publicTokenDao.delete(fileId);
    }
}
